.TITLE MEMAP .IDENT /13.05/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; ALL RIGHTS RESERVED. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; D. N. CUTLER 4-AUG-73 ; ; MODIFIED FOR RSX-11M-PLUS VERSION 2 BY: ; ; P. J. BEZEREDI ; D. R. DONCHIN ; B. S. MCCARTHY ; ; MODIFIED BY: ; ; B. S. MCCARTHY 23-MAY-82 13.01 ; ; BM255 -- ADD U$$UMR CONDITIONALS FOR P/OS ; ; J. M. LAWLER 02-DEC-82 13.02 ; ; JL144 -- MODIFY $RELUI TO RELOCATE SUPERMODE ; I-SPACE REFERENCES CORRECTLY ; ; MODIFIED FOR RSX-11M-PLUS V4.5 BY: ; ; D. CARROLL 15-Feb-1993 13.03 ; ; DC107 -- ADD P$$D74 CONDITIONAL TO FORCE CACHE ; BYPASS ON UMR USAGE WITHIN $MPUBM ; ; D. CARROLL 03-June-1993 13.04 ; ; DC219 -- INCLUDE SUPPORT FOR UNIBUS MEMORY WHEN ; DEALING WITH NPR DEVICES ; ; Modified for RSX-11M-PLUS V4.6 by: ; ; D. Carroll 18-Oct-1995 13.05 ; DC404 - Include PSECT definition to allow ICB pool to ; be fully extended during sysgen ; ; ; I/O RELATED ROUTINES ; ; ROUTINES DEALING WITH MEMORY MAPPING AND UMRS ; ; MACRO LIBRARY CALLS ; .MCALL F11DF$,HDRDF$,HWDDF$,PCBDF$,PKTDF$,SHDDF$,TCBDF$ F11DF$ ;DEFINE WINDOW AND LOCK BLOCK OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS SHDDF$ ;DEFINE SHADOW RECORDING OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS .IIF DF,K$$DAS&I$$CBP, .PSECT EXEC1 ;DC404 ;DC404 ;+ ; **-$MPPHY-MAP TO PHYSICAL ADDRESS ; ; THIS ROUTINE IS CALLED TO MAP A RELOCATION BIAS AND DISPLACEMENT ADDRESS TO AN ; 18 BIT PHYSICAL ADDRESS. IF THE INDICATED DEVICE IS NOT AN NPR AN DEVICE, ; THEN THE RELOCATION BIAS AND DISPLACEMENT ADDRESS ARE RETURNED TO THE CALLER. ; ELSE THE RELOCATION BIAS AND DISPLACEMENT ADDRESS ARE CONVERTED TO AN 18 BIT ; PHYSICAL ADDRESS WHICH IS RETURNED TO THE CALLER. ; ; INPUTS: ; ; R1=RELOCATION BIAS. ; R2=DISPLACEMENT ADDRESS. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; OUTPUTS: ; ; IF DEVICE IS AN NPR DEVICE ON AN 18-BIT MACHINE, THEN ; R1=HIGH ORDER 2 BITS OF PHYSICAL ADDRESS IN BITS 4 AND 5 ; R2=LOW ORDER 16 BITS OF PHYSICAL ADDRESS. ; IF DEVICE IS AN NPR DEVICE ON AN 11/70, THEN ; R1=HIGH ORDER 6 BITS OF PHYSICAL ADDRESS IN HIGH BYTE. ; R2=LOW ORDER 16 BITS OF PHYSICAL ADDRESS. ; IF DEVICE IS NOT AN NPR DEVICE, THEN ; R1=RELOCATION BIAS. ; R2=DISPLACEMENT ADDRESS. ; ; R0 AND R3 ARE PRESERVED ACROSS CALL. ;- $MPPHY::BITB #UC.NPR,U.CTL(R5) ;NPR DEVICE? BEQ 10$ ;IF EQ NO ASL R2 ;REMOVE APR6 BIAS FROM DISPLACEMENT ASL R2 ; CLC ;GET 2 BITS OF RELOCATION BIAS ROR R1 ; RORB R2 ;TO FILL 8 LOW ORDER BITS OF ADDRESS ASR R1 ; RORB R2 ; SWAB R2 ;SWAP TO COLLECT 8 MORE BITS BISB R1,R2 ;INSERT UPPER 8 BITS OF ADDRESS SWAB R2 ;SWAP BACK TO REAL ADDRESS CLRB R1 ;CLEAR LOW BYTE OF UPPER BITS .IF NDF M$$EXT ASH #-4,R1 ;PUT BITS <17:18> OF ADDRESS INTO ;BITS <4:5> .ENDC 10$: RETURN ; ;+ ; THE FOLLOWING TWO ENTRY POINTS WILL BE DEFINED ONLY WHEN ; 22-BIT ADDRESSING CODE IS DISABLED. THIS IS TO PREVENT THE ; DRIVERS FROM HAVING UNDEFINED SYMBOLS WHEN TASK BUILT. ;- .ENABL LSB .IF DF U$$UMR .IF NDF M$$EXT $MPUBM:: ;MAP 11/70 UNIBUS TO TRANSFER $STMAP:: ;SET MAPPING REGISTERS RETURN ;DUMMY RETURN ;+ ; **-$MPUB1-MAP UNIBUS TO MEMORY (ALTERNATE ENTRY). ; ; THIS ROUTINE IS CALLED BY UNIBUS NPR DEVICE DRIVERS TO LOAD THE ; NECESSARY UNIBUS MAP REGISTERS TO EFFECT A TRANSFER TO MAIN ; MEMORY ON AN 11/70 PROCESSOR WITH EXTENDED MEMORY. THIS ALTERNATE ; ENTRY POINT ALLOWS THE DRIVER TO SPECIFY A NON-STANDARD UMR MAPPING ; ASSIGNMENT BLOCK. ; ; INPUTS: ; ; R0=ADDRESS OF A UMR MAPPING ASSIGNMENT BLOCK. ; ; OUTPUTS: ; ; THE UNIBUS MAP REGISTERS NECESSARY TO EFFECT THE ; TRANSFER ARE LOADED. ; ; NOTE: REGISTER R3 IS PRESERVED ACROSS CALL. ;- .IFF ;NDF M$$EXT $MPUB1::MOV M.UMRN(R0),-(SP) ;SET COUNT OF REGISTERS TO LOAD MOVB M.BFVH(R0),R1 ;GET HIGH 6 BITS OF ADDRESS MOV M.BFVL(R0),R2 ;GET LOW 16 BITS OF ADDRESS MOV M.UMRA(R0),R0 ;GET ADDRESS OF FIRST MAP REGISTER BR 10$ ;GO LOAD THE UMRS ;+ ; **-$MPUBM-MAP UNIBUS TO MEMORY ; ; THIS ROUTINE IS CALLED BY UNIBUS NPR DEVICE DRIVERS TO LOAD THE ; NECESSARY UNIBUS MAP REGISTERS TO EFFECT A TRANSFER TO MAIN MEM- ; ORY ON AN 11/70 PROCESSOR WITH EXTENDED MEMORY. ; ; INPUTS: ; ; R4=ADDRESS OF DEVICE SCB. ; R5=ADDRESS OF DEVICE UCB. ; ; OUTPUTS: ; ; THE UNIBUS MAP REGISTERS NECESSARY TO EFFECT THE TRANSFER ; ARE LOADED. ; ; NOTE: REGISTER R3 IS PRESERVED ACROSS CALL. ;- $MPUBM::MOV S.KRB(R4),R0 ;GET KRB ADDRESS ADD K.OFF(R0),R0 ;R0=END OF UMR AREA+2 MOV M.UMRN-M.LGTH(R0),-(SP) ;PUSH COUNT OF UMR'S TO LOAD MOV -(R0),R2 ;GET LOW 16 BITS OF BUF ADDR (M.BFVL) MOVB -(R0),R1 ;GET HIGH ORDER 6 BITS (M.BFVH) MOV M.UMRA-M.BFVH(R0),R0 ;PICK UP ADDRESS OF FIRST UMR 10$: BEQ 20$ ; IF EQ, NO UMR ADDRESS TO LOAD MOV R2,(R0)+ ;LOAD LOW 16 BITS OF ADDRESS .IF DF P$$D74&P$$D70 ; 11/74 SUPPORT? MOV R1,(R0) ; Load the high 6 bits BIS #100000,(R0)+ ; and set the cache bypass bit .IFF ; DF,P$$D74&P$$D70 MOV R1,(R0)+ ; LOAD HIGH 6 BITS OF ADDRESS .ENDC ; DF,P$$D74&P$$D70 ADD #20000,R2 ;ADVANCE 8K BYTES ADC R1 ; SUB #4,(SP) ;ALL REGISTERS LOADED? BGT 10$ ;IF GT NO 20$: TST (SP)+ ;CLEAN STACK RETURN .ENDC ;NDF M$$EXT .ENDC ; DF U$$UMR .DSABL LSB ;+ ; **-$RELOC-RELOCATE USER VIRTUAL ADDRESS ; **-$RELUI-RELOCATE USER (I SPACE ONLY) VIRTUAL ADDRESS ; ; THIS ROUTINE IS CALLED TO TRANSFORM A 16 BIT USER VIRTUAL ADDRESS ; INTO A RELOCATION BIAS AND DISPLACEMENT IN BLOCK RELATIVE TO APR6. ; ; INPUTS: ; ; R0=USER VIRTUAL ADDRESS TO RELOCATE. ; ; OUTPUTS: ; ; R1=RELOCATION BIAS TO BE LOADED INTO PAR6. ; R2=DISPLACEMENT IN BLOCK PLUS 140000 (PAR6 BIAS). ; ; R0 AND R3 ARE PRESERVED ACROSS CALL. ;- .ENABL LSB .IF DF U$$DAS $RELUI::MOV #UINAR0,-(SP) ;PUSH ADDRESS OF USER I SPACE .IF DF S$$LIB BIT #20000,@#PS ;EXECUTED IN USER MODE ? BNE 10$ ;IF NE, YES MOV #SISAR0,(SP) ;SET TO SUPER I SPACE .ENDC ; DF S$$LIB BR 10$ ;ENTER COMMON CODE .ENDC ; DF U$$DAS $RELOC:: ;REFERENCE LABEL .IF DF U$$DAS!S$$LIB MOV #UISAR0,-(SP) ;ASSUME USER D SPACE .IFDF S$$LIB BIT #20000,@#PS ;EXECUTED IN USER MODE ? BNE 10$ ;IF MI YES MOV #SDSAR0,(SP) ;SET TO SUPER D SPACE .ENDC ; DF S$$LIB .IFTF ; U$$DAS!S$$LIB 10$: MOV R0,R1 ;COPY VIRTUAL ADDRESS ASH #-6,R1 ;CALCULATE BLOCK NUMBER BIC #177600,R1 ; MOV R0,R2 ;COPY VIRTUAL ADDRESS ASH #-12.,R2 ;CALCULATE APR INDEX BIC #177761,R2 ; .IFT ; DF U$$DAS!S$$LIB ADD (SP)+,R2 ;CALCULATE APR ADDRESS ADD (R2),R1 ;AND FETCH CONTENTS .IFF ; DF U$$DAS!S$$LIB ADD UISAR0(R2),R1 ;CALCULATE RELOCATION BIAS .ENDC ; DF U$$DAS!S$$LIB MOV R0,R2 ;COPY VIRTUAL ADDRESS BIC #177700,R2 ;CLEAR ALL BUT DISPLACEMENT IN BLOCK BIS #140000,R2 ;SET APR 6 BIAS RETURN ; .DSABL LSB ;+ ; **-$RELOM-RELOCATE AND MAP ADDRESS ; ; THIS ROUTINE IS CALLED TO TRANSFORM A 16 BIT USER VIRTUAL ADDRESS ; INTO A RELOCATION BIAS AND DISPLACEMENT IN BLOCK RELATIVE TO APR6 ; AND LOAD THESE VALUES FOR ACCESS BY THE CALLER. ; ; INPUTS: ; ; R0=USER VIRTUAL ADDRESS TO RELOCATE. ; ; OUTPUTS: ; ; R0=DISPLACEMENT IN BLOCK. ; KISAR6 IS LOADED WITH THE RELOCATION BIAS. ; ; R3 IS PRESERVED ACROSS CALL. ;- $RELOM::CALL $RELOC ;RELOCATE USER VIRTUAL ADDRESS MOV R1,KISAR6 ;SET KERNEL MAPPING REGISTER MOV R2,R0 ;SET DISPLACEMENT IN BLOCK ADDRESS RETURN ; ;+ ; **-$RELCD-RELOCATE,MAP AND CHECK A DPB/RDB/WDB ; ; THIS ROUTINE IS CALLED TO TRANSFORM A 16 BIT USER VIRTUAL ADDRESS ; INTO A BIAS/DISPLACEMENT PAIR. THE ROUTINE IS PRIMARILY FOR USE ; FROM THE DIRECTIVE DISPATCHER FOR DPBS/RDBS/WDBS. THE ROUTINE ; CHECKS TO SEE IF THE STRUCTURE OVERLAPS AN APR BOUNDARY. IF IT ; DOES, AND THE NEXT APR IS NOT MAPPED CONTIGUOUSLY WITH THE FIRST, ; A STATUS OF D.RS98 IS RETURNED, ELSE THE BLOCK IS MAPPED. ; ; INPUTS: ; ; R2=SIZE OF STRUCTURE IN BYTES ; R3=USER VIRTUAL ADDRESS ; ; OUTPUTS: ; ; D.RS98 RETURNED TO TASK IF STRUCTURE NOT PHYS. CONTIGUOUS ; ; R3=DISPLACEMENT ADDRESS IF USER VIRT. ADDR WAS VALID ; ; NOTE: KISAR6 IS DESTROYED (REMAPPED) IF USER VIRT. ADDR VALID ;- $RELCD::MOV R3,R0 ;COPY VIRTUAL ADDRESS ASH #-12.,R0 ;SHIFT APR SELECT TO BITS 1,2,3 BIC #177761,R0 ;CLEAR ALL BUT APR INDEX MOV UISAR0(R0),R1 ;GET PAGE ADDRESS REGISTER CONTENTS CMP #16,R0 ;MAPPED THROUGH APR 7 ? BEQ 10$ ;IF EQ YES - ALWAYS CHECK FOR WRAP MOV R1,-(SP) ;SAVE CONTENTS OF APR ADD #200,(SP) ;AND POINT IT AHEAD BY 4KW CMP (SP)+,UISAR0+2(R0) ;CONTIGUOUS WITH NEXT APR ? BEQ 20$ ;IF EQ YES - ALWAYS OK 10$: BIC #160000,R3 ;CLEAR APR SELECT FIELD OF V.A. ADD R3,R2 ;CALCULATE ADDRESS OF LAST BYTE DEC R2 ;IN DATA STRUCTURES CMP #20000,R2 ;OVERLAP APR BOUNDARY ? BLOS 30$ ;IF LOS YES - STRUCTURE IS NO CONTIGUOUS 20$: MOV R3,R2 ;COPY VIRTUAL ADDRESS ASH #-6,R2 ;SHIFT OFFSET BITS TO 0 THROUGH 6 BIC #177600,R2 ;CLEAR OUT ALL OTHERS ADD R1,R2 ;CALCULATE 32WD BLOCK NUMBER BIC #177700,R3 ;STRIP ALL BUT DISPLACEMENT BITS BIS #140000,R3 ;SET TO MAP THROUGH KISAR6 MOV R2,KISAR6 ;MAP TO USER BUFFER RETURN ; 30$: DRSTS D.RS98 ;"PART OF DPB OUT OF TASK'S ADDR SPACE" ;+ ; **-$ASUMR-ASSIGN UNIBUS MAPPING REGISTERS ; ; THIS ROUTINE IS CALLED TO ASSIGN A CONTIGUOUS SET OF UMR'S. NOTE THAT ; FOR THE SAKE OF SPEED, THE LINK WORD OF EACH MAPPING ASSIGNMENT BLOCK ; POINTS TO THE UMR ADDRESS (2ND) WORD OF THE BLOCK, NOT THE FIRST WORD. ; THE CURRENT STATE OF UMR ASSIGNMENT IS REPRESENTED BY A LINKED LIST OF ; MAPPING ASSIGNMENT BLOCKS, EACH BLOCK CONTAINING THE ADDRESS OF THE ; FIRST UMR ASSIGNED AND THE NUMBER OF UMR'S ASSIGNED TIMES 4. THE ; BLOCKS ARE LINKED IN THE ORDER OF INCREASING FIRST UMR ADDRESS. ; ; INPUTS: ; ; R0=POINTER TO A MAPPING REGISTER ASSIGNMENT BLOCK. ; M.UMRN(R0)=NUMBER OF UMR'S REQUIRED * 4. ; ; OUTPUTS: ; ; ALL REGISTERS ARE PRESERVED. ; ; C=0 IF THE UMR'S WERE SUCCESSFULLY ASSIGNED. ; ALL FIELDS OF THE MAPPING REGISTER ASSIGNMENT BLOCK ; ARE INITIALIZED AND THE BLOCK IS LINKED INTO ; THE ASSIGNMENT LIST. ; C=1 IF THE UMR'S COULD NOT BE ASSIGNED. ;- .IF DF M$$EXT&U$$UMR $ASUMR::SAVNR ;SAVE R4 AND R5 TST (R0)+ ;SKIP OVER LINK WORD (M.LNK) .IF DF U$$BME MOV M.BFVL-2(R0),R5 ; IF IT WAS, THEN M.UMVL SHOULD BE MOVB M.BFVH-2(R0),R4 ; GET BUFFER ADDRESS HGH ORDER PART ASHC #-6,R4 ; GET THE HIGHEST 16 BITS TO COMPARE CMP R5,$SYSIZ ; ARE WE IN THE UNIBUS MEMORY RANGE? BLO 5$ ; IF LO, NOPE ... CLR (R0) ; SET THE ADDRESS TO ZERO ;+ ; Create a UNIBUS address which will coorespond to the low order ; 18-bits of the memory address. ;- MOV M.BFVL-2(R0),M.UMVL-2(R0) ; LOAD THE LOW 16 BITS BIC #^C<6000>,R5 ; ISOLATE BITS 17,16 SWAB R5 ; GET IT INTO THE LOW BYTE (BITS 2,3) ASL R5 ; SHIFT AGAIN TO (3,4) ASL R5 ; AND AGAIN (4,5) MOVB R5,M.UMVH-2(R0) ; AND LOAD THE UNIBUS ADDRESS BR 30$ ; AND FINISH UP ... 5$: .ENDC ;DF,U$$BME MOV #$UMRHD+2,R5 ;POINT TO UMR ASSIGNMENT LISTHEAD + 2 10$: MOV R5,R4 ;SAVE POINTER TO PREVIOUS BEQ 30$ ;IF EQ ASSIGNMENT FAILURE MOV (R5),(R0) ;POINT TO NEXT FREE UMR (M.UMRA)(M.UMRA) ADD M.UMRN-M.UMRA(R5),(R0) ;(M.UMRA) .IF DF U$$BME MOV #UBMPR+<32.*4>,-(SP) ; PUSH POINTER PAST LAST UMR .IFF ;DF,U$$BME MOV #UBMPR+<31.*4>,-(SP) ;PUSH POINTER PAST LAST UMR .ENDC ;DF,U$$BME MOV -(R5),R5 ;POINT TO NEXT ASSIGNMENT BLOCK (M.LNK) BEQ 20$ ;IF EQ THERE IS NONE MOV (R5),(SP) ;SET NEXT ALLOCATED UMR ADDRESS (M.UMRA) 20$: SUB (R0),(SP) ;CALCULATE # OF FREE UMR'S * 4 (M.UMRA) CMP (SP)+,M.UMRN-M.UMRA(R0) ;ENOUGH UMR'S AVAILABLE? BLO 10$ ;IF LO NO MOV R0,-(R4) ;LINK NEW BLOCK TO PREVIOUS (M.LNK) MOV (R0),R4 ;SAVE FIRST UMR ADDRESS (M.UMRA) MOV R5,-2(R0) ;POINT NEW BLOCK TO NEXT IN LIST (M.LNK) MOV R4,R5 ;DUPLICATE FIRST UMR ADDRESS BICB #UBMPR!34,R5 ;MASK OUT ALL BUT HI 2 BITS IN LOW BYTE BIC R5,R4 ;MASK OUT HIGH BYTE HIGH 2 BITS ASR R5 ;SHIFT HIGH 2 BITS TO BITS 4 & 5 ASLB R4 ;CALCULATE HIGH BYTE OF LOW 16 BITS ASL R4 ; (LOSING 200 BIT FIRST) ASL R4 ; SWAB R4 ;FORM PROPER 16 BIT ADDRESS MOV M.BFVL-2(R0),M.UMVL-2(R0) ; GET ORIGINAL BUFFER ADDRESS BIC #^C<1>,M.UMVL-2(R0) ; WAS IT ODD? ADD R4,M.UMVL-2(R0) ; IF IT WAS, THEN M.UMVL SHOULD BE MOVB R5,M.UMVH-2(R0) ;SET BITS 4 & 5 30$: DEC R0 ;PNT BACK TO LINK WORD PRESERVING CARRY DEC R0 ; RETURN ; ;+ ; **-$DEUMR-DEASSIGN UNIBUS MAPPING REGISTERS ; ; THIS ROUTINE IS CALLED TO DEASSIGN A CONTIGUOUS BLOCK OF UMR'S. IF ; THE MAPPING ASSIGNMENT BLOCK IS NOT IN THE LIST, NO ACTION IS TAKEN. ; NOTE THAT FOR THE SAKE OF ASSIGNMENT SPEED, THE LINK WORD POINTS TO ; THE UMR ADDRESS (2ND) WORD OF THE ASSIGNMENT BLOCK. ; ; INPUTS: ; ; R2=POINTER TO ASSIGNMENT BLOCK. ; ; OUTPUTS: ; ; R0 AND R1 ARE PRESERVED. ;- $DEUMR::TST (R2)+ ;SKIP OVER LINK WORD (M.LNK) MOV #$UMRHD+2,R3 ;POINT TO ASSIGNMENT LISTHEAD + 2 10$: CMP -(R3),R2 ;IS IT THE NEXT ONE? (M.LNK) BEQ 20$ ;IF EQ YES MOV (R3),R3 ;ELSE POINT TO NEXT IN LIST (M.LNK) BNE 10$ ;IF NE THERE IS ONE BR 30$ ;ELSE MAPPING ASSIGNMENT BLK NOT IN LIST 20$: MOV -(R2),(R3) ;UNLINK THE BLOCK (M.LNK)(M.LNK) 30$: RETURN ; ;+ ; **-$STMP1-SET UP UNIBUS MAPPING ADDRESS (ALTERNATE ENTRY). ; ; THIS ENTRY CODE SETS UP AN ALTERNATE DATA STRUCTURE USED AS ; A UMR MAPPING ASSIGNMENT BLOCK AND CONTEXT STORAGE BLOCK, IN ; THE SAME MANNER AS $STMAP USES THE FORK BLOCK AND MAPPING ; BLOCK IN THE SCB, KRB. THE FORMAT OF THE STRUCTURE IS AS FOLLOWS: ; ; -------------------------- ; ! ! 4 WORDS USED FOR SAVING ; ! ! DRIVER'S CONTEXT IN CASE ; ! ! UMRS CAN'T BE MAPPED ; ! ! IMMEDIATELY. ; -------------------------- ; ! ! ; ! ! 6 WORDS USED AS A UMR ; ! ! MAPPING ASSIGNMENT BLOCK. ; ! ! ; ! ! ; ! ! ; -------------------------- ; ; ; INPUTS: ; ; R0=ADDRESS OF THE DATA STRUCTURE DEPICTED ABOVE. ; R4=ADDRESS OF DEVICE SCB. ; R5=ADDRESS OF DEVICE UCB. ; ; OUTPUTS: ; ; DATA STRUCTURE POINTERS SET UP FOR ENTRY TO $STMP2 IN $STMAP. ; ;- .ENABL LSB $STMP1::MOV S.FRK+10(R4),6(R0) ;SAVE DRIVER'S MAPPING MOV R0,R4 ;COPY BLOCK POINTER ADD #M.LGTH+10,R0 ;POINT PAST MAPPING BLOCK ADD #4,R4 ;POINT TO CONTEXT SAVE BLOCK BR 5$ ;SET UP THE UMR ADDRESS ;+ ; **-$STMAP-SET UP UNIBUS MAPPING ADDRESS ; ; THIS ROUTINE IS CALLED BY UNIBUS NPR DEVICE DRIVERS TO SET UP THE ; UNIBUS MAPPING ADDRESS, FIRST ASSIGNING THE UMR'S. IF THE UMR'S ; CANNOT BE ALLOCATED, THE DRIVER'S MAPPING ASSIGNMENT BLOCK IS PLACED ; IN A WAIT QUEUE AND A RETURN TO THE DRIVER'S CALLER IS EXECUTED. THE ; ASSIGNMENT BLOCK WILL EVENTUALLY BE DEQUEUED WHEN THE UMR'S ARE ; AVAILABLE AND THE DRIVER WILL BE REMAPPED AND RETURNED TO WITH R1-R5 ; PRESERVED AND THE NORMAL OUTPUTS OF THIS ROUTINE. THE DRIVER'S ; CONTEXT IS STORED IN THE ASSIGNMENT BLOCK AND FORK BLOCK WHILE IT IS ; BLOCKED AND IN THE WAIT QUEUE. ONCE A DRIVER'S MAPPING ASSIGNMENT ; BLOCK IS PLACED IN THE UMR WAIT QUEUE, IT IS NOT REMOVED FROM THE ; QUEUE UNTIL THE UMR'S ARE SUCCESSFULLY ASSIGNED. THIS STRATEGY ; ASSURES THAT WAITING DRIVERS WILL BE SERVICED FIFO AND THAT DRIVER'S ; WITH LARGE REQUESTS FOR UMR'S WILL NOT WAIT INDEFINATELY. ; ; INPUTS: ; ; R4=ADDRESS OF DEVICE SCB. ; R5=ADDRESS OF DEVICE UCB. ; (SP)=RETURN TO DRIVER'S CALLER. ; ; OUTPUTS: ; ; UNIBUS MAP ADDRESSES ARE SET UP IN THE DEVICE UCB AND THE ; ACTUAL PHYSICAL ADDRESS IS MOVED TO THE SCB. ; ; NOTE: REGISTERS R1, R2, AND R3 ARE PRESERVED ACROSS CALL. ;- $STMAP::MOV S.KRB(R4),R0 ;GET KRB ADDRESS ADD K.OFF(R0),R0 ;R0=LAST WORD+2 OF UMR AREA ADD #S.FRK+6,R4 ;POINT INTO FORK BLOCK 5$: MOV U.BUF+2(R5),-(R0) ;SAVE LOW 16 BITS OF ADDRESS (M.BFVL) MOVB U.BUF+1(R5),-(R0) ;SAVE HIGH 6 BITS OF ADDRESS (M.BFVH) DEC R0 ;POINT BACK TO NEXT WORD MOV U.CNT(R5),-(R0) ;TEMORARILY STORE BYTE COUNT (M.UMVL) CLR -(R0) ;INITIALIZE UMR COUNT (M.UMRN) BIT #1,M.BFVL-M.UMRN(R0) ;BUFFER ADDRESS ODD? BEQ 10$ ;IF EQ NO, ALL IS NORMAL INC 2(R0) ;IT'S ODD, WE MUST MAP ONE EXTRA BYTE 10$: ADD #4,(R0) ;INCREASE COUNT FOR ONE UMR (M.UMRN) SUB #20000,2(R0) ;REDUCE BYTE COUNT BY 8K BYTES (M.UMVL) BHI 10$ ;IF HI MORE BYTES TO GO TST -(R0) ;(M.UMRA) MOV -(R0),-(SP) ;SAVE POSSIBLE WAIT QUEUE LINK (M.LNK) CALL $ASUMR ;ATTEMPT TO ASSIGN REQUIRED UMR'S BCC 20$ ;IF CC SUCCESSFUL, CHECK FOR UMR WAIT TST (SP)+ ;CLEAR STACK MOV R5,(R4) ;SAVE R5 IN FORK BLOCK (S.FRK+6) MOV (SP)+,-(R4) ;SAVE DRIVER'S RETURN ADDRESS (S.FRK+4) MOV R0,-(R4) ;SAVE MAPPING BLOCK POINTER (S.FRK+2) CALL $WTUMR ;WAIT FOR CHANGE IN UMR ASSIGNMENT MOV (R4)+,R0 ;RESTORE MAPPING BLOCK POINTER (S.FRK+2) ADD #M.LGTH,R0 ;POINT PAST MAPPING BLOCK MOV (R4)+,-(SP) ;RESTORE DRIVER'S RETURN ADDR (S.FRK+4) MOV (R4),R5 ;RESTORE R5 (S.FRK+6) MOV 2(R4),KINAR5 ;REMAP DRIVER (S.FRK+10) .IF DF K$$DAS MOV 2(R4),KDSAR5 ;REMAP DRIVER IN D SPACE (S.FRK+10) .ENDC BR 5$ 20$: MOV U.SCB(R5),R4 ;RESTORE R4 MOV M.UMVL(R0),U.BUF+2(R5) ;STORE LOW WORD OF UMR VIRT ADDR MOVB M.UMVH(R0),U.BUF(R5) ;STORE HIGH SIX BITS CLRB U.BUF+1(R5) ;CLEAR HIGH-ORDER BYTE CMP $UMRWT,R0 ;WAS THIS CALLER WAITING? BNE 30$ ;IF NE NO MOV (SP),$UMRWT ;DEQUEUE CURRENT CALLER'S BLOCK BNE 30$ ;IF NE NOT END OF LIST MOV #$UMRWT,$UMRWT+2 ;UPDATE LAST IN LIST POINTER 30$: TST (SP)+ ;CLEAR STACK .ENABL LSB ;+ ; **-$DQUMR-DEQUEUE FROM UMR WAIT ; ; CONTROL IS TRANSFERRED HERE TO SEE IF A DRIVER IS WAITING FOR UMR ; ASSIGNMENT. FIRST THE CALLING DRIVER IS CALLED BACK AS A COROUTINE. ; WHEN THE CALLING DRIVER ISSUES A RETURN BACK TO THIS ROUTINE, A CHECK ; IS MADE TO SEE IF ANY DRIVERS ARE WAITING FOR UMR'S. IF SO THE WAIT- ; ING DRIVER'S CONTEXT IS RESTORED WITHOUT ACTUALLY DEQUEUEING THE ; MAPPING ASSIGNMENT BLOCK AND CONTROL IS PASSED BACK TO THE ORIGINAL ; UMR ASSIGNMENT ROUTINE. ; ; INPUTS: ; ; (SP)=RETURN ADDRESS TO DRIVER'S CALLER.. ; ; OUTPUTS: ; ; IF ANYONE IS WAITING THEIR CONTEXT IS RESTORED AND THE ALLOCA- ; TION ROUTINE IS CALLED BACK. ;- .ENABL LSB $DQUMR::CALL @(SP)+ ;CALL THE CALLER AS COROUTINE MOV $UMRWT,R0 ;ANYONE WAITING FOR UMR ASSIGNMENT? BEQ 10$ ;IF EQ HE HAS SINCE GONE AWAY ROL -(SP) ;SAVE SENSE OF C-BIT TST (R0)+ ;POINT TO SAVED R1 MOV (R0)+,R1 ;RESTORE SAVED REGISTERS MOV (R0)+,R2 ; MOV (R0)+,R3 ; MOV (R0)+,R4 ; CALL @(R0)+ ;CALL ROUTINE ROR (SP)+ ;RESET C BIT TO ENTRY CONDITION RETURN ; ;+ ; **-$WTUMR-WAIT FOR CHANGE IN UMR STATE ; ; THIS ROUTINE STORES R1-R4 AND THE RETURN PC IN THE MAPPING ASSIGNMENT ; AND QUEUES THE BLOCK IN THE UMR WAIT QUEUE FOR A SUBSEQUENT RECALL TO ; THE CALLER WHEN THE STATE OF UMR ASSIGNMENT CHANGES. NOTE THAT IT IS ; POSSIBLE FOR THE MAPPING ASSIGNMENT BLOCK TO ALREADY BE IN THE WAIT ; QUEUE, BUT IF IT IS IT CAN ONLY BE AT THE HEAD OF THE QUEUE. ; ; INPUTS: ; ; R0=POINTER TO UMR ASSIGNMENT BLOCK ; ; OUTPUTS: ; ; THE ASSIGNMENT BLOCK IS QUEUED IN THE UMR WAIT QUEUE. ; THE CALLER IS EVENTUALLY RETURNED AT SYSTEM STATE WITH R1-R4 ; PRESERVED. ;- $WTUMR::MOV (SP)+,12(R0) ;STORE RETURN ADDR TO ALLOCATE ROUTINE CMP R0,$UMRWT ;MAPPING ASSIGNMENT BLK ALREADY IN LIST? BEQ 5$ ;IF EQ YES MOV R0,@$UMRWT+2 ;LINK BLOCK TO LAST IN QUEUE MOV R0,$UMRWT+2 ;UPDATE LAST IN LIST POINTER CLR (R0) ;ZERO LINK WORD 5$: TST (R0)+ ;POINT PAST LINK WORD MOV R1,(R0)+ ;SAVE CALLER'S REGISTERS MOV R2,(R0)+ ; MOV R3,(R0)+ ; MOV R4,(R0)+ ; 10$: RETURN ;RETURN TO CALLER'S CALLER .DSABL LSB .ENDC ; DF M$$EXT&U$$UMR ;+ ; **-$RELOP-RELOCATE UNIBUS PHYSICAL ADDRESS ; ; THIS ROUTINE RELOCATES A UNIBUS PHYSICAL ADDRESS TO A KISAR6 ; BIAS AND DISPLACEMENT. ; ; INPUTS: ; ; R0=BYTE OFFSET FROM ADDRESS IN U.BUF+1 AND U.BUF+2 ; R5=UCB ADDRESS ; U.BUF+1(R5)=HIGH ORDER BITS OF PHYSICAL ADDRESS ; U.BUF+2(R5)=LOW ORDER BITS OF PHYSICAL ADDRESS ; ; OUTPUTS: ; ; KISAR6=CALCULATED BIAS (MAPPED SYSTEM) ; R1=REAL ADDRESS OR DISPLACEMENT ;- .IF NDF R$$PRO $RELOP::MOV R0,-(SP) ;SAVE OFFSET INTO BUFFER MOV U.BUF+2(R5),R1 ;GET LOW BITS OF PHYSICAL ADDRESS MOVB U.BUF+1(R5),R0 ;GET HIGH BITS OF PHYSICAL ADDRESS ADD (SP),R1 ;ADD OFFSET INTO BUFFER ADC R0 ;... ASHC #10.,R0 ;CALCULATE DISPLACEMENT AND BIAS ASHC #-10.,R1 ;... MOV R0,KISAR6 ;LOAD RELOCATION BIAS ADD #140000,R1 ;SET TO MAP THRU APR6 MOV (SP)+,R0 ;RESTORE BYTE OFFSET RETURN ; .ENDC ; NDF R$$PRO ;+ ; **-$SWACD-SAVE MAPPING, CALL ACD AS A CO-ROUTINE, THEN REMAP DRIVER ; **-$SWAC1-CALL ACD AS A CO-ROUTINE, THEN REMAP DRIVER ; ; THESE ROUTINES ARE CALLED BY THE FULL DUPLEX TERMINAL DRIVER TO ; SWITCH PROCESSING TO AN ANCILLARY CONTROL DRIVER (ACD). SINCE THE ; ACD REQUIRES APRS 5 AND 6, THE DRIVER MAPPING IS FIRST SAVED (IF ENTRY ; AT $SWACD), THEN THE ACD IS CALLED AS A CO-ROUTINE VIA A DISPATCH ; TABLE CONTAINED IN THE ANCILLARY CONTROL BLOCK (ACB). WHEN THE ACD ; ACD RETURNS, THIS ROUTINE REMAPS THE DRIVER AND RETURNS CONTROL TO IT. ; ; INPUTS: ; ; R0=DISPATCH TABLE OFFSET (IF ENTRY AT $SWACD). ; R0=ACB ADDRESS (IF ENTRY AT $SWAC1). ; R5=POINTER TO OFFSET U.TSTA WITHIN THE TERMINAL'S UCB. ; 2(SP)=DISPATCH TABLE OFFSET (IF ENTRY AT $SWAC1). ; 4(SP)=APR5 BIAS OF TERMINAL DRIVER (IF ENTRY AT $SWAC1). ; ; OUTPUTS: ; ; R0 IS DESTROYED. ;- .IF DF T$$ACD $SWACD::MOV KINAR5,-(SP) ;SAVE TERMINAL DRIVER MAPPING .IF DF K$$DAS MOV KDSAR5,-(SP) ;SAVE TERMINAL DRIVER D-SPACE MAPPING .IFTF ;K$$DAS MOV R0,-(SP) ;PUT ENTRY POINT OFFSET ON STACK MOV U.ACB-U.TSTA(R5),R0 ;GET ACB ADDRESS ASSUME A.REL,0 $SWAC1::MOV (R0),KINAR5 ;MAP THE ANCILLARY CONTROL DRIVER .IFT ;K$$DAS MOV (R0),KDSAR5 ;MAP THE ANCILLARY CONTROL DRIVER D-SPACE .IFTF ;K$$DAS ADD A.DIS(R0),(SP) ;ADD DISPATCH TABLE ADDR TO THE OFFSET MOV @(SP),(SP) ;GET THE ENTRY POINT ADDRESS CALL @(SP)+ ;CALL THE ACD .IFT ;K$$DAS MOV (SP)+,KDSAR5 ;UPON RETURN, REMAP TTDRV D-SPACE .ENDC ;K$$DAS MOV (SP)+,KINAR5 ;REMAP THE TERMINAL DRIVER RETURN ;AND THEN RETURN TO IT .ENDC ;T$$ACD .END